<!DOCTYPE html>	<!--表示文档类型为HTML文档-->
<html>
	<head><!--文档头部-->
		<!--使用UTF-8字符编码，无此句在某些浏览器会出现乱码-->
		<meta charset = "utf-8">
		<!--文档标题，会显示在网页标题栏-->
		<title>2018031701040.蔡妙格</title>
	</head>
	
	<body><!--文档主体-->
		<!--绘图区域的id，以及宽度和高度，用WebGL绘制的图形将显示在该canvas中-->
		<canvas id="webgl" width="600" height="600">
		对不起，你的浏览器不支持HTML5的canvas元素！<!--出错时显示这句话-->
		</canvas>
		<p>方向键控制视点</p>
		<div>
		材质：
		<select id="material" size="1"> <!--size为直接可见的条目数-->
		<option value="0">黄铜</option>
		<option value="1">铬</option>
		<option value="2">翡翠</option>
		<option value="3">黑曜石</option>
		<option value="4">紫罗兰</option>
		</select>
		</div>
		
		<!--以下为用到的shader程序和JavaScript程序，程序类型由type属性决定，
		顶点Shader程序和片元Shader程序有id，因为在JavaScript程序中需要对其
		进行访问，而JavaScript程序无id-->
		
		<!--片元光照计算-->
		<!--顶点Shader程序-->
		<script id="vertex-fShading" type="x-shader/x-vertex">
		attribute vec3 a_Position;	// 输入三维顶点坐标(建模坐标系)
		attribute vec3 a_Normal;	// 顶点法向(建模坐标系)

		varying vec3 v_fN;	// 法向(观察坐标系)
		varying vec3 v_fE;	// 观察向量(观察坐标系)
		varying vec3 v_fL;	// 光照向量(观察坐标系)

		uniform mat4 u_matModel;		// 模型矩阵
		uniform mat4 u_matView;			// 观察矩阵
		uniform mat4 u_Projection;		// 投影矩阵
		uniform mat3 u_NormalMat;		// 法向变换矩阵
		
		uniform vec4 u_LightPosition;	// 光源位置/方向(世界坐标系)
		
		attribute vec2 a_Texcoord;
		varying vec2 v_Texcoord;
		void main(){
			// 将顶点坐标转到观察坐标系下(在观察坐标系计算光照)
			vec3 pos = (u_matView * u_matModel * vec4(a_Position, 1.0)).xyz;
			v_fE = normalize(-pos);		// 观察者方向向量
			// 计算观察坐标系下法向
			v_fN = normalize(u_NormalMat * a_Normal);
			
			v_fL = (u_matView * u_LightPosition).xyz;  // 从顶点指向光源的向量(观察坐标系)
			if( u_LightPosition.w != 0.0 ) {  // 近距离光源
				v_fL = v_fL - pos.xyz;
			}
			v_fL = normalize(v_fL);	// 归一化
			
			v_Texcoord = a_Texcoord;
	
			// 裁剪坐标系下顶点坐标
			gl_Position = u_Projection * vec4(pos, 1.0); 
		}
		</script>
		
		<!--片元Shader程序-->
		<script id="fragment-fShading" type="x-shader/x-fragment">
		precision mediump float;	// 浮点数精度为中等
		varying vec3 v_fN;	// 法向(观察坐标系)
		varying vec3 v_fE;	// 观察向量(观察坐标系)
		varying vec3 v_fL;	// 光照向量(观察坐标系)

		uniform float u_Shininess;	// 高光系数
		// 光源亮度与材质反射系数的乘积
		uniform vec3 u_AmbientProduct, u_DiffuseProduct, u_SpecularProduct; 
	
		varying vec2 v_Texcoord;
		uniform sampler2D u_Sampler;
		void main(){
			// 归一化输入的向量
			vec3 N = normalize(v_fN);
			vec3 E = normalize(v_fE);
			vec3 L = normalize(v_fL);

			vec3 H = normalize( L + E );	// 半角向量
    
			vec3 ambient = u_AmbientProduct;	// 环境反射分量

			// 漫反射分量
			float Kd = max(dot(L, N), 0.0);
			vec3 diffuse = Kd * u_DiffuseProduct;
    
			// 镜面反射分量
			vec3 specular;
			if( Kd == 0.0 ) {  // 即dot(L, N) <= 0
				specular = vec3(0.0, 0.0, 0.0);
			} 
			else{
				float Ks = pow( max(dot(N, H), 0.0), u_Shininess );
				specular = Ks * u_SpecularProduct;
			}

			// 得到最终颜色(分量值超过1为自动截断)
			gl_FragColor = vec4(ambient + diffuse + specular, 1.0);
			
			vec4 fragColor = vec4(ambient + diffuse,1.0);
			
			gl_FragColor = fragColor * texture2D(u_Sampler,v_Texcoord) + vec4(specular,1.0);
		}
		</script>
		
		<!--下面是辅助我们进行程序编写的3个JavaScript程序-->
		<script type="text/javascript" src="./Common/webgl-utils.js"></script>
		<script type="text/javascript" src="./Common/initShaders.js"></script>
		<script type="text/javascript" src="./Common/MV.js"></script>
		<!--主程序-->
		<script type="text/javascript" src="40CMG_12Texture.js"></script>
	</body>
</html>